﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using Microsoft.Windows.Design.PropertyEditing;

namespace DenisVuyka.Controls.PropertyGrid.Controls
{
  public class CategoryContainer : ContentControl
  {
    public static readonly DependencyProperty CategoryProperty =
      DependencyProperty.Register("Category", typeof(CategoryItem), typeof(CategoryContainer),
      new PropertyMetadata(null, new PropertyChangedCallback(CategoryContainer.OnCategoryPropertyChanged)));

    public static readonly DependencyProperty PropertiesMatchFilterProperty =
     DependencyProperty.Register("PropertiesMatchFilter", typeof(bool), typeof(CategoryContainer),
     new FrameworkPropertyMetadata(true));

    public static readonly DependencyProperty OwningCategoryContainerProperty =
      DependencyProperty.RegisterAttached("OwningCategoryContainer", typeof(CategoryContainer), typeof(CategoryContainer),
      new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits));


    public CategoryContainer()
    {
      SetOwningCategoryContainer(this, this);

      Binding bindingFilter = new Binding("Category.PropertiesMatchFilter")
      {
        Source = this,
        Mode = BindingMode.OneWay
      };

      base.SetBinding(PropertiesMatchFilterProperty, bindingFilter);
    }

    public override void OnApplyTemplate()
    {
      base.OnApplyTemplate();
    }

    private static void OnCategoryPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
      CategoryContainer container = (CategoryContainer)d;
      if (e.NewValue == null) return;
      CategoryItem oldValue = (CategoryItem)e.OldValue;
      if (oldValue != null)
        oldValue.FilterApplied -= new EventHandler<PropertyFilterAppliedEventArgs>(container.OnFilterApplied);

      CategoryItem newValue = (CategoryItem)e.NewValue;
      if (newValue != null)
        newValue.FilterApplied += new EventHandler<PropertyFilterAppliedEventArgs>(container.OnFilterApplied);
    }

    private void OnFilterApplied(object source, PropertyFilterAppliedEventArgs args)
    {
      if (!args.Filter.IsEmpty)
        this.Category.IsExpanded = this.PropertiesMatchFilter;
      else
        this.Category.IsExpanded = true;
    }

    public CategoryItem Category
    {
      get { return (CategoryItem)GetValue(CategoryProperty); }
      set { SetValue(CategoryProperty, value); }
    }

    public bool PropertiesMatchFilter
    {
      get { return (bool)GetValue(PropertiesMatchFilterProperty); }
      set { SetValue(PropertiesMatchFilterProperty, value); }
    }

    public static CategoryContainer GetOwningCategoryContainer(DependencyObject obj)
    {
      if (obj == null) throw new ArgumentNullException("obj");
      return (CategoryContainer)obj.GetValue(OwningCategoryContainerProperty);
    }

    public static void SetOwningCategoryContainer(DependencyObject obj, CategoryContainer value)
    {
      if (obj == null) throw new ArgumentNullException("obj");
      obj.SetValue(OwningCategoryContainerProperty, value);
    }
  }
}